home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / gcc / ixemlsrc.lha / ixemul / ixnet / res_comp.c < prev    next >
C/C++ Source or Header  |  1996-03-13  |  8KB  |  347 lines

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if defined(LIBC_SCCS) && !defined(lint)
  35. static char sccsid[] = "@(#)res_comp.c  6.22 (Berkeley) 3/19/91";
  36. #endif /* LIBC_SCCS and not lint */
  37.  
  38. #include <sys/param.h>
  39. #include <arpa/nameser.h>
  40. #include <netinet/in.h>
  41. #include <resolv.h>
  42. #include <stdio.h>
  43.  
  44. static dn_find();
  45.  
  46. /*
  47.  * Expand compressed domain name 'comp_dn' to full domain name.
  48.  * 'msg' is a pointer to the begining of the message,
  49.  * 'eomorig' points to the first location after the message,
  50.  * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
  51.  * Return size of compressed name or -1 if there was an error.
  52.  */
  53. int
  54. dn_expand(msg, eomorig, comp_dn, exp_dn, length)
  55.     const u_char *msg, *eomorig, *comp_dn;
  56.     u_char *exp_dn;
  57.     int length;
  58. {
  59.     register u_char *cp, *dn;
  60.     register int n, c;
  61.     u_char *eom;
  62.     int len = -1, checked = 0;
  63.  
  64.     dn = exp_dn;
  65.     cp = (u_char *)comp_dn;
  66.     eom = exp_dn + length;
  67.     /*
  68.      * fetch next label in domain name
  69.      */
  70.         while ((n = *cp++)) {
  71.         /*
  72.          * Check for indirection
  73.          */
  74.         switch (n & INDIR_MASK) {
  75.         case 0:
  76.             if (dn != exp_dn) {
  77.                 if (dn >= eom)
  78.                     return (-1);
  79.                 *dn++ = '.';
  80.             }
  81.             if (dn+n >= eom)
  82.                 return (-1);
  83.             checked += n + 1;
  84.             while (--n >= 0) {
  85.                 if ((c = *cp++) == '.') {
  86.                     if (dn + n + 2 >= eom)
  87.                         return (-1);
  88.                     *dn++ = '\\';
  89.                 }
  90.                 *dn++ = c;
  91.                 if (cp >= eomorig)      /* out of range */
  92.                     return(-1);
  93.             }
  94.             break;
  95.  
  96.         case INDIR_MASK:
  97.             if (len < 0)
  98.                 len = cp - comp_dn + 1;
  99.             cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
  100.             if (cp < msg || cp >= eomorig)  /* out of range */
  101.                 return(-1);
  102.             checked += 2;
  103.             /*
  104.              * Check for loops in the compressed name;
  105.              * if we've looked at the whole message,
  106.              * there must be a loop.
  107.              */
  108.             if (checked >= eomorig - msg)
  109.                 return (-1);
  110.             break;
  111.  
  112.         default:
  113.             return (-1);                    /* flag error */
  114.         }
  115.     }
  116.     *dn = '\0';
  117.     if (len < 0)
  118.         len = cp - comp_dn;
  119.     return (len);
  120. }
  121.  
  122. /*
  123.  * Compress domain name 'exp_dn' into 'comp_dn'.
  124.  * Return the size of the compressed name or -1.
  125.  * 'length' is the size of the array pointed to by 'comp_dn'.
  126.  * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
  127.  * is a pointer to the beginning of the message. The list ends with NULL.
  128.  * 'lastdnptr' is a pointer to the end of the arrary pointed to
  129.  * by 'dnptrs'. Side effect is to update the list of pointers for
  130.  * labels inserted into the message as we compress the name.
  131.  * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
  132.  * is NULL, we don't update the list.
  133.  */
  134. int
  135. dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
  136.     const u_char *exp_dn;
  137.     u_char *comp_dn, **dnptrs, **lastdnptr;
  138.     int length;
  139. {
  140.     register u_char *cp, *dn;
  141.     register int c, l;
  142.         u_char **cpp = NULL, **lpp = NULL, *sp, *eob;
  143.     u_char *msg;
  144.  
  145.     dn = (u_char *)exp_dn;
  146.     cp = comp_dn;
  147.     eob = cp + length;
  148.     if (dnptrs != NULL) {
  149.         if ((msg = *dnptrs++) != NULL) {
  150.             for (cpp = dnptrs; *cpp != NULL; cpp++)
  151.                 ;
  152.             lpp = cpp;    /* end of list to search */
  153.         }
  154.     } else
  155.         msg = NULL;
  156.     for (c = *dn++; c != '\0'; ) {
  157.         /* look to see if we can use pointers */
  158.         if (msg != NULL) {
  159.             if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
  160.                 if (cp+1 >= eob)
  161.                     return (-1);
  162.                 *cp++ = (l >> 8) | INDIR_MASK;
  163.                 *cp++ = l % 256;
  164.                 return (cp - comp_dn);
  165.             }
  166.             /* not found, save it */
  167.             if (lastdnptr != NULL && cpp < lastdnptr-1) {
  168.                 *cpp++ = cp;
  169.                 *cpp = NULL;
  170.             }
  171.         }
  172.         sp = cp++;    /* save ptr to length byte */
  173.         do {
  174.             if (c == '.') {
  175.                 c = *dn++;
  176.                 break;
  177.             }
  178.             if (c == '\\') {
  179.                 if ((c = *dn++) == '\0')
  180.                     break;
  181.             }
  182.             if (cp >= eob) {
  183.                 if (msg != NULL)
  184.                     *lpp = NULL;
  185.                 return (-1);
  186.             }
  187.             *cp++ = c;
  188.         } while ((c = *dn++) != '\0');
  189.         /* catch trailing '.'s but not '..' */
  190.         if ((l = cp - sp - 1) == 0 && c == '\0') {
  191.             cp--;
  192.             break;
  193.         }
  194.         if (l <= 0 || l > MAXLABEL) {
  195.             if (msg != NULL)
  196.                 *lpp = NULL;
  197.             return (-1);
  198.         }
  199.         *sp = l;
  200.     }
  201.     if (cp >= eob) {
  202.         if (msg != NULL)
  203.             *lpp = NULL;
  204.         return (-1);
  205.     }
  206.     *cp++ = '\0';
  207.     return (cp - comp_dn);
  208. }
  209.  
  210. /*
  211.  * Skip over a compressed domain name. Return the size or -1.
  212.  */
  213. int
  214. __dn_skipname(comp_dn, eom)
  215.     const u_char *comp_dn, *eom;
  216. {
  217.     register u_char *cp;
  218.     register int n;
  219.  
  220.     cp = (u_char *)comp_dn;
  221.     while (cp < eom && (n = *cp++)) {
  222.         /*
  223.          * check for indirection
  224.          */
  225.         switch (n & INDIR_MASK) {
  226.         case 0:     /* normal case, n == len */
  227.             cp += n;
  228.             continue;
  229.         default:    /* illegal type */
  230.             return (-1);
  231.         case INDIR_MASK:    /* indirection */
  232.             cp++;
  233.         }
  234.         break;
  235.     }
  236.     return (cp - comp_dn);
  237. }
  238.  
  239. /*
  240.  * Search for expanded name from a list of previously compressed names.
  241.  * Return the offset from msg if found or -1.
  242.  * dnptrs is the pointer to the first name on the list,
  243.  * not the pointer to the start of the message.
  244.  */
  245. static int
  246. dn_find(exp_dn, msg, dnptrs, lastdnptr)
  247.     u_char *exp_dn, *msg;
  248.     u_char **dnptrs, **lastdnptr;
  249. {
  250.     register u_char *dn, *cp, **cpp;
  251.     register int n;
  252.     u_char *sp;
  253.  
  254.         for (cpp = dnptrs; (cpp < lastdnptr); cpp++) {
  255.         dn = exp_dn;
  256.         sp = cp = *cpp;
  257.                 while ((n = *cp++)) {
  258.             /*
  259.              * check for indirection
  260.              */
  261.             switch (n & INDIR_MASK) {
  262.             case 0:     /* normal case, n == len */
  263.                 while (--n >= 0) {
  264.                     if (*dn == '.')
  265.                         goto next;
  266.                     if (*dn == '\\')
  267.                         dn++;
  268.                     if (*dn++ != *cp++)
  269.                         goto next;
  270.                 }
  271.                 if ((n = *dn++) == '\0' && *cp == '\0')
  272.                     return (sp - msg);
  273.                 if (n == '.')
  274.                     continue;
  275.                 goto next;
  276.  
  277.             default:    /* illegal type */
  278.                 return (-1);
  279.  
  280.             case INDIR_MASK:    /* indirection */
  281.                 cp = msg + (((n & 0x3f) << 8) | *cp);
  282.             }
  283.         }
  284.         if (*dn == '\0')
  285.             return (sp - msg);
  286.     next:    ;
  287.     }
  288.     return (-1);
  289. }
  290.  
  291. /*
  292.  * Routines to insert/extract short/long's. Must account for byte
  293.  * order and non-alignment problems. This code at least has the
  294.  * advantage of being portable.
  295.  *
  296.  * used by sendmail.
  297.  */
  298.  
  299. u_short
  300. _getshort(msgp)
  301.     u_char *msgp;
  302. {
  303.     register u_char *p = (u_char *) msgp;
  304. #ifdef vax
  305.     /*
  306.      * vax compiler doesn't put shorts in registers
  307.      */
  308.     register u_long ul;
  309. #else
  310.     register u_short ul;
  311. #endif
  312.  
  313.     ul = *p++ << 8;
  314.     return ((u_short)(ul | *p));
  315. }
  316.  
  317. u_long
  318. _getlong(msgp)
  319.     u_char *msgp;
  320. {
  321.     register u_char *p = (u_char *) msgp;
  322.     register u_long ul;
  323.  
  324.     ul = *p++; ul <<= 8;
  325.     ul |= *p++; ul <<= 8;
  326.     ul |= *p++; ul <<= 8;
  327.     return (ul | *p);
  328. }
  329.  
  330. void
  331. __putshort(register u_short s, register u_char *msgp)
  332. {
  333.     msgp[1] = s;
  334.     msgp[0] = s >> 8;
  335. }
  336.  
  337. void
  338. __putlong(l, msgp)
  339.     register u_long l;
  340.     register u_char *msgp;
  341. {
  342.     msgp[3] = l;
  343.     msgp[2] = (l >>= 8);
  344.     msgp[1] = (l >>= 8);
  345.     msgp[0] = l >> 8;
  346. }
  347.